package com.cskaoyan.aspect;

import com.cskaoyan.service.RedisService;
import com.cskaoyan.util.HttpUtils;
import com.cskaoyan.util.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.logging.Logger;

/**
 * redis缓存切面 只能配合注解实现返回固定数据的方法只用从数据库查一次
 *
 * 会变动的数据还不知道怎么缓存，不知道怎么通用的判断数据是否更新
 */
@Aspect
@Component
public class RedisCacheAspect {
    private static final Logger logger = Logger.getGlobal();
    @Autowired
    private RedisService redisService;

    @Pointcut("@annotation(com.cskaoyan.anno.RedisCache)")
    public void requireRedisCache() {
    }

    @Around("requireRedisCache()")
    public Object redisCacheSupport(ProceedingJoinPoint joinPoint) throws Throwable {
        //从缓存取
        HttpServletRequest request = HttpUtils.getHttpRequest();
        String methodName = joinPoint.getSignature().getName();
        String permission = StringUtils.uriToPermission(request.getRequestURI());
        String key = permission + ":" + methodName;//key 格式 admin:role:permission:service方法名
        Object value = null;
        try {
            value = redisService.get(key);
        } catch (Exception e) {
            logger.info("Redis连接异常");//防止有同学没有打开redis
        }
        if (value != null) {
            logger.info("使用缓存 " + key);
            return value;
        }

        //从数据库取
        Object result = joinPoint.proceed();

        //放入缓存
        try {
            redisService.set(key, result);
        } catch (Exception e) {
            logger.info("Redis连接异常");//防止有同学没有打开redis
        }
        logger.info("使用缓存失败，从数据库获取 " + key);

        return result;
    }

}
